package reflects

import (
	"reflect"
)

type Entity struct {
	key      reflect.Type
	val      reflect.Value
	FieldNum int     //字段长度
	Field    []Field //字段数组
}

//字段
type Field struct {
	Key  string            //字段名
	Type reflect.Type      //字段类型
	Tag  reflect.StructTag //字段tag
	Val  interface{}       //字段值
}

func New(i interface{}) Entity {
	data := Entity{
		key: GetKeyElem(reflect.TypeOf(i)),
		val: GetValElem(reflect.ValueOf(i)),
	}
	if data.key.Kind() != reflect.Struct {
		return Entity{}
	}
	data.FieldNum = data.key.NumField()
	for i := 0; i < data.FieldNum; i++ {
		data.Field = append(data.Field, Field{
			Key:  data.getKeyField(i).Name,
			Type: data.getKeyField(i).Type,
			Tag:  data.getKeyField(i).Tag,
			Val:  data.getValField(i).Interface(),
		})
	}
	return data
}

func (this Entity) getKeyField(i int) reflect.StructField {
	return this.key.FieldByIndex([]int{i})
}

func (this Entity) getValField(i int) reflect.Value {
	return this.val.FieldByIndex([]int{i})
}

func (this Entity) GetTag(i int, key string) string {
	if i >= 0 && i+1 <= this.FieldNum {
		return this.getKeyField(i).Tag.Get(key)
	}
	return ""
}

//取出元素,去除指针
func (this Entity) getKeyElem() reflect.Type {
	return GetKeyElem(this.key)
}

//获取路径
func GetPath(i interface{}) string {
	r := reflect.TypeOf(i)
	r = GetKeyElem(r)
	return r.PkgPath()
}

func GetKeyElem(r reflect.Type) reflect.Type {
	for r.Kind() == reflect.Ptr {
		r = r.Elem()
	}
	return r
}

func GetValElem(r reflect.Value) reflect.Value {
	for r.Kind() == reflect.Ptr {
		r = r.Elem()
	}
	return r
}
